import glmatrix = require("gl-matrix");
import {Coordinate} from "../geo/Coordinate";
const mat4 = glmatrix.mat4;

export class TileCoord {
  z: number;
  x: number;
  y: number;
  w: number;
  id: number;
  posMatrix: glmatrix.mat4;

  constructor(z: number, x: number, y: number, w?: number | void) { // w: wrap number
    // assert(!isNaN(z) && z >= 0 && z % 1 === 0);
    // assert(!isNaN(x) && x >= 0 && x % 1 === 0);
    // assert(!isNaN(y) && y >= 0 && y % 1 === 0);

    if (w === undefined || isNaN(w)) w = 0;

    this.z = +z;
    this.x = +x;
    this.y = +y;
    this.w = +w;

    // calculate id
    w *= 2;
    if (w < 0) w = w * -1 - 1;
    const dim = 1 << this.z;
    this.id = ((dim * dim * w + dim * this.y + this.x) * 32) + this.z;

    // for caching pos matrix calculation when rendering
    this.posMatrix = mat4.create();
  }

  toCoordinate(sourceMaxZoom: number | void): Coordinate {
    const zoom = Math.min(this.z, sourceMaxZoom === undefined ? this.z : sourceMaxZoom);
    const tileScale = Math.pow(2, zoom);
    const row = this.y;
    const column = this.x + tileScale * this.w;
    return new Coordinate(column, row, zoom);
  }
}